<template>
  <div class="ontologyConstruction">
    <el-row :gutter="20">
      <el-col :span="12">
        <div class="grid-item" style="height: calc(100vh - 60px)">
          <div class="grid-content ep-bg-purple">
            <div class="header_2">
              <h3>
                标准化接入模型
                <span class="question-mark"
                  ><Icon icon="tdesign:help-circle"
                /></span>
              </h3>
            </div>
            <div class="box1">
              <div class="btn-box" style="padding-top: 10px">
                <el-row justify="center">
                  <el-col :span="7" style="text-align: center">
                    <el-button
                      size="large"
                      :style="{
                        backgroundColor:
                          selectedBody === '本体1' ? '#409EFF' : '#f5f5f5',
                        color: selectedBody === '本体1' ? '#fff' : '#000'
                      }"
                      @click="handleBodyClick('本体1')"
                      >电子制造业数据采集语义本体</el-button
                    >
                  </el-col>
                  <!-- 其他按钮 -->
                  <el-col :span="7" style="text-align: center">
                    <el-button
                      size="large"
                      :style="{
                        backgroundColor:
                          selectedBody === '本体2' ? '#409EFF' : '#f5f5f5',
                        color: selectedBody === '本体2' ? '#fff' : '#000'
                      }"
                      @click="handleBodyClick('本体2')"
                      >纺织行业数据采集语义本体</el-button
                    >
                  </el-col>
                  <el-col :span="5" style="text-align: center">
                    <el-button
                      size="large"
                      :style="{
                        backgroundColor:
                          selectedBody === '本体3' ? '#409EFF' : '#f5f5f5',
                        color: selectedBody === '本体3' ? '#fff' : '#000'
                      }"
                      @click="handleBodyClick('本体3')"
                      >数据标准化语义本体</el-button
                    >
                  </el-col>
                  <el-col :span="5" style="text-align: center">
                    <el-button
                      size="large"
                      :style="{
                        backgroundColor:
                          selectedBody === '本体4' ? '#409EFF' : '#f5f5f5',
                        color: selectedBody === '本体4' ? '#fff' : '#000'
                      }"
                      @click="handleBodyClick('本体4')"
                      >数据预处理语义本体</el-button
                    >
                  </el-col>
                </el-row>
              </div>
              <div class="fileSelection">
                <!-- //上传本体时候用，本体上传完删除或者注释代码 -->
                <div class="update-body">
                  <!-- <el-input
                    v-model="fileXml"
                    style="max-width: 500px; margin-left: 10px"
                    class="input-with-select"
                  >
                    <template #append>
                      <el-upload
                        ref="uploadRef"
                        action="#"
                        :show-file-list="false"
                        :auto-upload="false"
                        :on-exceed="handleExceedXml"
                        accept=".xml"
                        :limit="1"
                        :on-change="handleChangeXml"
                      >
                        <el-button type="primary" @click="handleFileUpload"
                          >...</el-button
                        >
                      </el-upload>
                    </template>
                  </el-input> -->
                  <!-- <el-select
                    v-model="firstBodyValue"
                    clearable
                    placeholder="请选择本体"
                    size="small"
                    style="width: 200px"
                  >
                    <el-option
                      value="本体1"
                      label="电子制造业数据采集语义本体"
                    />
                    <el-option value="本体2" label="纺织行业数据采集语义本体" />
                    <el-option value="本体3" label="数据标准化本体" />
                    <el-option value="本体4" label="数据预处理语义本体" />
                  </el-select>
                  <el-button
                    type="primary"
                    size="small"
                    @click="updateFirstBody"
                    >第一次上传本体</el-button
                  > -->
                </div>

                <div class="fl-update-main">
                  <div class="fl-txt-update">修改:</div>
                  <div class="fl-update-box">
                    <el-tooltip content="添加" placement="top">
                      <div class="drag-class" @mousedown="dragNode" />
                    </el-tooltip>
                    <el-tooltip content="删除" placement="top">
                      <div class="delete-node" @click="deleteNode">
                        <Icon
                          style="font-size: 20px; color: #999"
                          icon="ic:baseline-delete-forever"
                        />
                      </div>
                    </el-tooltip>
                    <el-tooltip content="撤回" placement="top">
                      <div class="undoEdge" @click="undoNodeEdge">
                        <Icon
                          style="font-size: 20px; color: #999"
                          icon="ic:round-undo"
                        />
                      </div>
                    </el-tooltip>
                  </div>
                </div>
              </div>
              <div ref="wrapperRef" class="container-box">
                <div id="container" />
              </div>
            </div>
          </div>
          <el-row>
            <el-col :span="12" />
            <el-col :span="6">
              <el-button
                type="primary"
                style="padding: 10px 40px; margin: 10px 0"
                @click="downloadXml"
                >保存本地</el-button
              >
            </el-col>
            <el-col :span="6">
              <!-- <el-button
              type="primary"
              style="padding: 10px 20px; margin: 10px;"
              @click="downloadXml"
            >下载</el-button> -->
              <el-button
                type="primary"
                style="padding: 10px 40px; margin: 10px 0"
                @click="saveBody"
                >保存上传</el-button
              >
            </el-col>
          </el-row>
        </div>
      </el-col>
      <el-col :span="12">
        <div v-if="isShow" class="grid-item" style="height: calc(100vh - 60px)">
          <div class="grid-content ep-bg-purple">
            <div class="header_1">
              <h3>
                本体构建
                <span class="question-mark1"
                  ><Icon icon="tdesign:help-circle"
                /></span>
              </h3>
            </div>
            <div class="object">
              <span class="title">对象属性</span>
              <el-select
                v-model="dataObj"
                style="width: 100%"
                @change="dataObjChange"
              >
                <el-option
                  v-for="item in object_options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
            </div>
            <div class="classfication">
              <div class="title">类别</div>
              <el-select
                v-model="dataType"
                style="width: 100%"
                @change="dataTypeChange"
              >
                <el-option
                  v-for="item in type_options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
            </div>
          </div>
          <div class="grid-content ep-bg-purple">
            <div class="header_1">
              <h3>
                实例接入<span class="question-mark22"
                  ><Icon icon="tdesign:help-circle"
                /></span>
              </h3>
            </div>
            <div class="mapping">
              <div class="title">实例化</div>
              <el-select
                v-model="selectedValue"
                clearable
                placeholder="请选择实例"
                size="large"
                style="width: 240px"
                @change="selectChange"
              >
                <el-option
                  v-for="item in selectedOption"
                  :key="item"
                  :label="item"
                  :value="item"
                />
              </el-select>
              <span style="padding-left: 20px">本体实例接入处理时间:</span>
              <el-tag
                class="time-box"
                :style="{
                  margin: '10px 20px 15px 20px',
                  fontSize: '16px',
                  color: 'grey',
                  backgroundColor: '#f2f3f5'
                }"
              >
                {{ time1 }}
              </el-tag>
            </div>
          </div>
          <!-- 映射赋值 -->
          <!-- <div class="grid-content ep-bg-purple">
            <div class="header_1">
              <h3>
                实例映射
                <span class="question-mark2"
                  ><Icon icon="tdesign:help-circle"
                /></span>
              </h3>
            </div>
            <div class="mapping">
              <div class="title">映射</div>
              <el-input
                v-model="dataMap"
                placeholder="请输入"
                style="width: 100%"
              />
            </div>
            <div class="btns">
              <el-button
                type="primary"
                style="padding: 10px 120px"
                @click="setNodeKeyId"
                >映射</el-button
              >
              <span style="padding-left: 20px">本体实例接入处理时间:</span>
              <el-tag
                class="time-box"
                :style="{
                  margin: '10px 20px 15px 20px',
                  fontSize: '16px',
                  color: 'grey',
                  backgroundColor: '#f2f3f5'
                }"
              >
                {{ time1 }}
              </el-tag>
            </div>
          </div> -->
          <div class="grid-content ep-bg-purple">
            <div class="header_1">
              <h3>
                属性赋值
                <span class="question-mark3"
                  ><Icon icon="tdesign:help-circle"
                /></span>
              </h3>
              （提示：选择“数据”才能进行属性赋值）
            </div>
            <div v-if="dataObj === '5'" class="mapping">
              <span class="title">数据</span>
              <el-select
                v-model="selectedValue1"
                style="width: 100%; max-width: 220%"
                class="input-with-select"
                placeholder="请选择"
                @change="handleChangeWrapper"
              >
                <el-option
                  v-for="file in fileList"
                  :key="file.id"
                  :label="file.path"
                  :value="file.path"
                />
              </el-select>
            </div>
            <div v-if="dataObj === '5'" class="btns">
              <el-button
                type="primary"
                style="padding: 10px 120px"
                @click="setNodeKeyData"
                >赋值</el-button
              >
              <span style="padding-left: 20px">本体实例数据处理响应时间:</span>
              <el-tag
                class="time-box"
                :style="{
                  margin: '10px 20px 15px 20px',
                  fontSize: '16px',
                  color: 'grey',
                  backgroundColor: '#f2f3f5'
                }"
              >
                {{ time2 }}
              </el-tag>
            </div>
          </div>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<script setup>
import {
  LogicFlow,
  RectNode,
  RectNodeModel,
  HtmlNode,
  HtmlNodeModel
} from "@logicflow/core";
import "@logicflow/core/dist/style/index.css";
import { DndPanel, Snapshot } from "@logicflow/extension";
import "@logicflow/extension/lib/style/index.css";
import { message } from "@/utils/message";
import { Icon } from "@iconify/vue";
import { ref, onMounted, nextTick } from "vue";
import { getLfData, addLfData, codeList } from "@/api/ontologyConstruction";
import { addData, getData } from "@/api/logicflowApi";
import { genFileId } from "element-plus";
import { fetchFileList } from "@/api/dataProcessing";

const keyData = ref("");
const dataObj = ref("0");
const dataType = ref("0");
const time1 = ref("");
const time2 = ref("");
const dataMap = ref("");
const isShow = ref(0);
const fileName = ref("");
const fileXml = ref();
const selectedValue = ref("");
const selectedValue1 = ref("");
const selectedOption = ref([]);
const selectedBody = ref("本体1"); // 默认选中的本体
const object_options = [
  {
    value: "0",
    label: "总部"
  },
  {
    value: "1",
    label: "工厂"
  },
  {
    value: "2",
    label: "设备"
  },
  {
    value: "3",
    label: "边缘网关"
  },
  {
    value: "4",
    label: "控制器"
  },
  {
    value: "5",
    label: "数据"
  },
  {
    value: "6",
    label: "传感器"
  },
  {
    value: "7",
    label: "通信协议"
  },
  {
    value: "8",
    label: "预处理方法"
  }
];

const type_options = [
  {
    value: "0",
    label: "子类"
  },
  {
    value: "1",
    label: "父类"
  }
];
const options = [
  {
    label: "file in 20240712 1421.json",
    value: "file in 20240712 1421.json"
  },
  {
    label: "file in 20240712 1422.json",
    value: "file in 20240712 1422.json"
  },
  {
    label: "file in 20240712 1423.json",
    value: "file in 20240712 1423.json"
  },
  {
    label: "file in 20240712 14224.json",
    value: "file in 20240712 1424.json"
  }
];
const edgeId = ref();
const container = ref();
const width = ref();
const height = ref();
const wrapperRef = ref();
const fileList = ref([]); // 文件列表
// 定义本体对应的实例选项
const ontologyOptions = {
  本体1: [
    "电子制造业AGV小车",
    "电子制造业回流焊接炉",
    "电子制造业贴片机",
    "电子制造业真空上板机",
    "电子制造业风冷存储机",
    "电子制造业异常筛选机",
    "电子制造业平移机"
  ],
  本体2: ["纺织行业大圆机", "纺织行业喷水织机", "纺织行业整经机"],
  本体3: [
    "AGV小车数据标准化",
    "回流焊接炉数据标准化",
    "贴片机数据标准化",
    "真空上板机数据标准化",
    "大圆机数据标准化",
    "喷水织机数据标准化",
    "整经机数据标准化"
  ],
  本体4: [
    "AGV小车数据预处理",
    "回流焊接炉数据预处理",
    "贴片机数据预处理",
    "真空上板机数据预处理",
    "大圆机数据预处理",
    "喷水织机数据预处理",
    "整经机数据预处理"
  ]
};

// 点击本体按钮时的处理函数
function handleBodyClick(body) {
  selectedBody.value = body;
  selectedOption.value = ontologyOptions[body];
  selectedValue.value = ""; // 重置选中的实例
  // 如果需要重新加载本体数据
  getBody(body);
}

onMounted(() => {
  createSvg(); // 先创建画布
  getFileList();
  getBody("本体1"); // 页面加载时默认获取“本体1”的数据
  selectedOption.value = ontologyOptions[selectedBody.value];
  // Vue 更新后再获取容器尺寸

  nextTick(() => {
    const data = {};
  });
  createSvg();
  //getLfNodeData();
});

// 获取文件列表函数
const getFileList = async () => {
  const queryParams = {
    path: "kafka" // 保持与 Postman 中一致
  };

  try {
    // 发送请求获取文件列表，传递整个对象而不是字符串
    const result = await fetchFileList(queryParams);

    if (result && result.data) {
      console.log("Received file list data:", result.data.data.data);
      fileList.value = result.data.data.data; // 将 data 数组赋值给 fileList
    } else {
      console.error("未收到文件列表数据");
    }
  } catch (error) {
    console.error("获取文件列表失败:", error.message); // 打印错误信息
    if (error.response) {
      // 如果有响应，打印响应状态和数据
      console.error("Error response status:", error.response.status);
      console.error("Error response data:", error.response.data);
    } else if (error.request) {
      // 如果没有响应，打印请求信息
      console.error("No response received, request details:", error.request);
    } else {
      // 其他错误
      console.error("Error setting up request:", error.message);
    }
  }
};
// 第一次上传本体
const firstBodyValue = ref("");
function updateFirstBody() {
  if (firstBodyValue.value) {
    const graphData = lf.value.getGraphData();
    addData({
      type: firstBodyValue.value,
      msg: JSON.stringify(graphData)
    }).then(res => {
      if (res.status === 200) {
        message("本体保存成功", { type: "success" });
      }
    });
  } else {
    message("请选择需要保存的本体", { type: "error" });
  }
}

// 选择框获取已经添加的实例
const selectedBodyId = ref(null);
function selectChange(value) {
  selectedBodyId.value = value;
  dataObj.value = "";

  if (value) {
    const startTime = Date.now(); // 记录开始时间

    getData({
      type: value
    }).then(res => {
      if (res.status === 200) {
        message("实例已接入", { type: "success" });
      }
      const endTime = Date.now(); // 记录结束时间
      const responseTime = ((endTime - startTime) / 1000).toFixed(2); // 计算响应时间（秒）

      console.log("响应时间：", responseTime, "秒");

      let LFData = JSON.parse(res.data.text);
      lf.value.clearData();
      lf.value.render(LFData);
      isShow.value = true;

      // 实例接入的时间
      time1.value = responseTime;
    });
  }
}

// 保存实例
const saveBody = () => {
  if (selectedBodyId.value) {
    const graphData = lf.value.getGraphData();
    addData({
      type: selectedBodyId.value,
      msg: JSON.stringify(graphData)
    }).then(res => {
      if (res.status === 200) {
        message("实例保存成功", { type: "success" });
      }
    });
  }
};
// const selectedBody = ref("");
// 获取本体
function getBody(val) {
  console.log("getBody called with value:", val); // 打印传入的参数值
  selectedBody.value = val; // 更新当前选中的本体
  dataObj.value = "";
  time1.value = "";
  getData({
    type: val
  })
    .then(res => {
      console.log("Response received:", res); // 打印完整的响应对象

      if (res.status === 200) {
        console.log("Status is 200, processing data..."); // 打印状态检查信息

        message("本体已下载", { type: "success" });

        try {
          let LFData = JSON.parse(res.data.text); // 尝试解析 JSON 数据
          console.log("Parsed LFData:", LFData); // 打印解析后的数据

          lf.value.clearData();
          lf.value.render(LFData);
          isShow.value = true;
        } catch (error) {
          console.error("Error parsing JSON:", error); // 捕获并打印 JSON 解析错误
        }
      } else {
        console.error("Unexpected status code:", res.status); // 打印意外的状态码
      }
    })
    .catch(error => {
      console.error("Request failed:", error); // 捕获并打印请求错误
    });
}

// 创建画布
const lf = ref();
const nodeId = ref();
const createSvg = () => {
  lf.value = new LogicFlow({
    container: document.querySelector("#container"),
    edgeType: "bezier",
    plugins: [DndPanel, Snapshot],
    width: 600,
    height: 500,
    background: {
      backgroundColor: "#f2f3f5"
    },
    grid: false,
    style: {
      rect: {
        rx: 5,
        ry: 5,
        strokeWidth: 1,
        fill: "#c1c1c1",
        stroke: "#e5e7eb"
      },
      baseEdge: {
        stroke: "#0c78e1",
        strokeWidth: 2
      }
    },
    adjustEdge: false,
    edgeSelectedOutline: true,
    edgeTextEdit: true
  });
  const showCenterHeight = wrapperRef.value.getBoundingClientRect().height;
  const showCenterWidth = wrapperRef.value.getBoundingClientRect().width;
  lf.value.resize(showCenterWidth, showCenterHeight);
  const data = {
    nodes: [
      {
        id: 1,
        type: "htmlNode",
        x: 100,
        y: 50,
        text: {
          value: "Headquarters"
        },
        properties: {
          keyObj: "",
          keyClass: "",
          keyId: "hello",
          keyData: ""
        }
      },
      {
        id: 2,
        type: "htmlNode",
        x: 100,
        y: 150,
        text: {
          value: "FACTORY"
        },
        properties: {
          keyObj: "",
          keyClass: "",
          keyId: "hello",
          keyData: ""
        }
      },
      {
        id: 3,
        type: "htmlNode",
        x: 400,
        y: 50,
        text: {
          value: "protocol"
        },
        properties: {
          keyObj: "",
          keyClass: "",
          keyId: "hello",
          keyData: ""
        }
      },
      {
        id: 4,
        type: "htmlNode",
        x: 400,
        y: 150,
        text: {
          value: "Headquaters"
        },
        properties: {
          keyObj: "",
          keyClass: "",
          keyId: "hello",
          keyData: ""
        }
      },
      {
        id: 5,
        type: "htmlNode",
        x: 250, //200
        y: 270,
        text: {
          value: "Decive"
        },
        properties: {
          keyObj: "",
          keyClass: "",
          keyId: "hello",
          keyData: ""
        }
      },
      {
        id: 6,
        type: "htmlNode",
        x: 80,
        y: 390,
        text: {
          value: "Headquaters"
        },
        properties: {
          keyObj: "",
          keyClass: "",
          keyId: "hello",
          keyData: ""
        }
      },
      {
        id: 7,
        type: "htmlNode",
        x: 400,
        y: 390,
        text: {
          value: "Headquaters"
        },
        properties: {
          keyObj: "",
          keyClass: "",
          keyId: "hello",
          keyData: ""
        }
      },
      {
        id: 8,
        type: "htmlNode",
        x: 400,
        y: 480,
        text: {
          value: "Data"
        },
        properties: {
          keyObj: "",
          keyClass: "",
          keyId: "hello",
          keyData: ""
        }
      }
    ],
    edges: [
      {
        type: "bezier",
        sourceNodeId: 2,
        targetNodeId: 1
      },
      {
        type: "bezier",
        sourceNodeId: 4,
        targetNodeId: 3
      },
      {
        type: "bezier",
        sourceNodeId: 5,
        targetNodeId: 2
      },
      {
        type: "bezier",
        sourceNodeId: 5,
        targetNodeId: 4
      },
      {
        type: "bezier",
        sourceNodeId: 5,
        targetNodeId: 6
      },
      {
        type: "bezier",
        sourceNodeId: 5,
        targetNodeId: 7
      },
      {
        type: "bezier",
        sourceNodeId: 7,
        targetNodeId: 8
      }
    ]
  };

  // 自定义矩形节点
  // class CustomNodeView extends RectNode {
  // }

  // class CustomNodeModel extends RectNodeModel {
  //     initNodeData(data) {
  //       super.initNodeData(data);
  //       this.width = 100;
  //       this.height = 40;
  //       this.radius = 3;
  //     }
  // }
  // const customRectNode = {
  //   type: "customNode",
  //   view: CustomNodeView,
  //   model: CustomNodeModel,
  // }
  // 自定义html节点
  class CustomHtmlNode extends HtmlNode {
    setHtml(rootEl) {
      const { properties } = this.props.model;
      const el = document.createElement("div");
      el.className = "node-main";
      const html = `
          <div class="node-box">
            <div class="node-top"></div>
            <div class="node-bottom">
              <span class="node-keyId">${properties.keyId ? properties.keyId : ""}</span>
              <span class="node-keyData">${properties.keyData ? properties.keyData : ""}</span>
            </div>
          </div>`;
      el.innerHTML = html;
      rootEl.innerHTML = "";
      rootEl.appendChild(el);
      // window.stop = (ev) => {
      //   ev.stopPropagation();
      // };
      // window.setData = () => {
      //   const { graphModel, model } = this.props;
      //   graphModel.eventCenter.emit('custom:button-click', model);
      // };
    }
  }

  class CustomHtmlNodeModel extends HtmlNodeModel {
    setAttributes() {
      this.width = 140;
      this.height = 70;
      this.text.editable = true;
    }

    formatText(data) {
      data.text = {
        value: data.text.value || "",
        x: data.x,
        y: data.y - 10
      };
    }
  }

  const autoHtmlNode = {
    type: "htmlNode",
    view: CustomHtmlNode,
    model: CustomHtmlNodeModel
  };
  lf.value.register(autoHtmlNode);
  lf.value.render();
  // 单击选中节点获取节点数据
  lf.value.on("node:click,edge:click", eventObject => {
    if (eventObject.data.type === "bezier") {
      edgeId.value = eventObject.data.id;
    } else {
      nodeId.value = eventObject.data.id;
      getNodeAtt(nodeId.value);
    }
  });
};

// 获取后端请求关系图数据
const getLfNodeData = () => {
  // let timeNum = new Date().getTime();
  getLfData("2024-04-18 14:51:21")
    .then(res => {
      // console.log(res)
      if (res.status === 200) {
        const nodes = [];
        const edges = [];
        for (let i = 0; i < res.data.nodes.length; i++) {
          nodes.push({
            id: res.data.nodes[i].id,
            type: res.data.nodes[i].type,
            x: res.data.nodes[i].x,
            y: res.data.nodes[i].y,
            text: {
              value: res.data.nodes[i].text
            },
            properties: {
              keyClass: res.data.nodes[i].properties
                ? res.data.nodes[i].properties.split(",")[0]
                : "",
              keyData: res.data.nodes[i].properties
                ? res.data.nodes[i].properties.split(",")[1]
                : "",
              keyId: res.data.nodes[i].properties
                ? res.data.nodes[i].properties.split(",")[2]
                : "",
              keyObj: res.data.nodes[i].properties
                ? res.data.nodes[i].properties.split(",")[3]
                : ""
            }
          });
        }
        for (let i = 0; i < res.data.edges.length; i++) {
          edges.push({
            type: res.data.edges[i].type,
            sourceNodeId: res.data.edges[i].sourceNodeId,
            targetNodeId: res.data.edges[i].targetNodeId
          });
        }
        let data = {};
        data = {
          nodes: nodes,
          edges: edges
        };
        lf.value.clearData();
        lf.value.render(data);
      }
    })
    .catch(error => {
      console.log(error);
    });
};
// 添加新的关系图数据到后端
const addLfNode = () => {
  const graphData = lf.value.getGraphData();
  const nodes = [];
  const edges = [];
  for (let i = 0; i < graphData.nodes.length; i++) {
    nodes.push({
      id: graphData.nodes[i].id,
      type: graphData.nodes[i].type,
      x: graphData.nodes[i].x,
      y: graphData.nodes[i].y,
      text: graphData.nodes[i].text.value,
      properties:
        graphData.nodes[i].properties.keyClass +
        "," +
        graphData.nodes[i].properties.keyData +
        "," +
        graphData.nodes[i].properties.keyId +
        "," +
        graphData.nodes[i].properties.keyObj
    });
  }
  for (let i = 0; i < graphData.edges.length; i++) {
    edges.push({
      type: graphData.edges[i].type,
      sourceNodeId: graphData.edges[i].sourceNodeId,
      targetNodeId: graphData.edges[i].targetNodeId
    });
  }
  let data = {};
  data = {
    nodes: nodes,
    edges: edges
  };

  addLfData(data)
    .then(res => {
      if (res.status === 200) {
        message("添加成功", { type: "success" });
      }
    })
    .catch(error => {
      message(error.message, { type: "error" });
    });
};

// 画布以外的拖拽栏
const dragNode = () => {
  lf.value.dnd.startDrag({
    type: "htmlNode",
    text: "测试拖拽"
  });
};
// 撤销上一步
const undoNodeEdge = () => {
  lf.value.undo();
};
// 基于边的id删除边
const deleEdge = () => {
  lf.value.deleteEdge(edgeId.value);
};
// 下载流程图
const downloadNode = () => {
  lf.value.getSnapshot();
};
// 获取流程图json数据
const getGraphJson = () => {
  const graphData = lf.value.getGraphData();
};
// 删除节点
const deleteNode = () => {
  lf.value.deleteNode(nodeId.value);
  lf.value.deleteEdge(edgeId.value);
};
// 修改节点文本值
const editNodeText = (id, value) => {
  lf.value.updateText(id, value);
};
// 获取节点的所有上一级
const nodeFather = () => {
  const nodeff = lf.value.getNodeIncomingNode(nodeId.value);
};

// 获取节点本身
const getNodeModel = () => {
  console.log(lf.value.getNodeDataById(nodeId.value));
};
// 给选中节点添加工厂id自定义属性
const setNodeKeyId = () => {
  if (dataMap.value) {
    // time1.value = Math.random() * (0.5 - 0.1) + 0.1;
    // time1.value = time1.value.toFixed(2);
    lf.value.setProperties(nodeId.value, {
      keyId: dataMap.value
    });
  }
};
// 给选中节点添加数据自定义属性
const setNodeKeyData = () => {
  if (selectedValue1.value) {
    const startTime = Date.now(); // 记录开始时间

    keyData.value = "2000";
    lf.value.setProperties(nodeId.value, {
      keyData: keyData.value
    });

    const endTime = Date.now(); // 记录结束时间
    const executionTimeMs = endTime - startTime; // 执行时间（毫秒）
    console.log("执行时间：", executionTimeMs, "毫秒");

    // 如果需要显示秒数，可以除以 1000
    const executionTimeSec = (executionTimeMs / 1000).toFixed(3); // 保留三位小数
    console.log("执行时间：", executionTimeSec, "秒");

    // 本体实例数据处理响应时间
    time2.value = executionTimeSec;
  }
};

// 给选中对象添加自定义属性
const dataObjChange = e => {
  lf.value.setProperties(nodeId.value, {
    keyObj: e
  });
};
// 给选中类别添加自定义属性
const dataTypeChange = e => {
  lf.value.setProperties(nodeId.value, {
    keyClass: e
  });
};
// 获取节点自定义属性
const getNodeAtt = id => {
  const NodeData = lf.value.getProperties(id);
  dataMap.value = NodeData.keyId;
  keyData.value = NodeData.keyData;
  dataObj.value = NodeData.keyObj;
  dataType.value = NodeData.keyClass;
};

let fileRef = ref();
let fileUp = ref();
// 选择文件时被调用，将他赋值给fileRef
const handleChange = (file, fileList) => {
  fileRef.value = file;
  fileName.value = file.name;
  fileUp.value = file;
};

// 覆盖前一个选择的
const handleExceed = files => {
  fileRef.value.clearFiles();
  const file = files[0];
  file.uid = genFileId();
  fileRef.value.handleStart(file);
};

// 下载xml文件
const downloadXml = () => {
  const lfData = JSON.stringify(lf.value.getGraphData());
  download("logic-flow.xml", lfData);
};
// 下载文件
const download = (filename, text) => {
  var element = document.createElement("a");
  element.setAttribute(
    "href",
    "data:text/plain;charset=utf-8," + encodeURIComponent(text)
  );
  element.setAttribute("download", filename);
  element.style.display = "none";
  document.body.appendChild(element);
  element.click();
  document.body.removeChild(element);
};

// 第一次上传本体
function handleChangeXml(files) {
  fileXml.value = files.name;
  const file = files.raw;
  const reader = new FileReader();
  reader.onload = event => {
    if (event.target) {
      let data = event.target.result;
      lf.value.clearData();
      lf.value.render(JSON.parse(data));
    }
  };
  reader.readAsText(file);
  isShow.value = 1;
}

// 覆盖前一个文件
const uploadRef = ref();
function handleExceedXml(files) {
  uploadRef.value.clearFiles();
  const file = files[0];
  file.uid = genFileId();
  uploadRef.value.handleStart(file);
}
function handleFileUpload1() {
  // 处理文件上传逻辑
  const inputElement = document.createElement("input");
  inputElement.type = "file";
  inputElement.accept = ".xml"; // 可以根据需要设置文件类型限制
  inputElement.onchange = event => {
    const selectedFile = event.target.files[0];
    if (selectedFile) {
      file.value = selectedFile.name;
      // 可以根据需要将文件信息存储在其他变量中
    }
  };
  inputElement.click();
}
</script>

<style>
.node-main {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  padding: 5px;
}

.node-box {
  box-sizing: border-box;
  width: 130px;
  height: 60px;
  background-color: #fff;
  border: 2px solid #e5e7eb;
  border-radius: 6px;
  box-shadow: 0px 6px 3px -2px rgba(0, 0, 0, 0.2);
}

.node-top {
  width: 100%;
  height: 30px;
  background-color: #fff;
  border-radius: 6px 6px 0 0;
}

.node-bottom {
  width: 100%;
  height: 30px;
  line-height: 30px;
  background-color: #e5e7eb;
  border-radius: 0 0 6px 6px;
  padding: 0 3px;
  font-size: 12px;
  display: flex;
  justify-content: space-between;
  overflow: hidden;
}

.node-keyId {
  flex: 1;
}

.node-keyData {
  flex: 1;
  text-align: right;
}

.container-box {
  position: relative;
}

#container {
  width: 100%;
  height: calc(100vh - 230px);
}

.lf-dndpanel {
  padding: 0;
  left: 500px;
  background-color: #c1c1c1;
}

.rectClass {
  width: 30px;
  height: 20px;
  border: #000 1px solid;
  border-radius: 4px;
  margin-top: 0;
}

.unClass {
  width: 16px;
  height: 16px;
}

.fileSelection {
  display: flex;
  justify-content: right;
  padding: 10px 20px 0 0;
}

.update-body {
  display: flex;
  align-items: center;
  padding-right: 10px;
}

.fl-update-main {
  display: flex;
  align-items: center;
}

.fl-txt-update {
  font-size: 14px;
  color: #606266;
  margin-right: 6px;
}

.fl-update-box {
  display: flex;
  align-items: center;
  background-color: #fff;
  padding: 4px 6px;
}

.drag-class {
  width: 40px;
  height: 24px;
  background-color: #d2cfcf;
  border: 1px solid e7e9ed; /* 添加黑色边框 */
  border-radius: 4px; /* 设置四边圆角 */
  margin-right: 14px;
  cursor: pointer;
}

.delete-node {
  width: 40px;
  height: 24px;
  background-color: #d2cfcf;
  cursor: pointer;
  border-radius: 4px;
  border: 1px solid #e7e9ed;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-right: 14px;
}

.undoEdge {
  width: 40px;
  height: 24px;
  background-color: #ccc;
  border-radius: 4px;
  border: 1px solid #e7e9ed;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
}
</style>

<style lang="scss" scoped>
.ontologyConstruction {
  width: 100%;
  height: calc(100vh - 200px);
  font-size: 16px;

  .grid-item {
    border-radius: 10px;
    box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2);
    background-color: #fff;
  }
  .question-mark {
    position: relative;
    display: inline-block;
    width: 20px;
    text-align: center;
    line-height: 20px;
    margin-left: 5px; /* 将右侧间距改为5px */
    font-size: 18px; /* 修改字体大小 */
  }

  .question-mark:hover::after {
    /* 使用 ::after 伪元素来显示文本 */
    content: " 使用本体实现资源数据的标准化描述及展示";
    position: absolute;
    top: -10px; /* 调整提示文本位置，使其位于问号的上方 */
    left: calc(100% + 5px); /* 设置文本距离问号图案的距离 */
    padding: 5px;
    background-color: #fff;
    color: #000;
    border: 1px solid #000;
    border-radius: 4px;
    display: block;
    max-width: 400px; /* 设置最大宽度 */
    white-space: nowrap; /* 防止文本换行 */
    word-wrap: break-word;
    font-size: 14px;
  }
  .question-mark1 {
    position: relative;
    display: inline-block;
    width: 20px;
    text-align: center;
    line-height: 20px;
    margin-left: 5px; /* 将右侧间距改为5px */
    font-size: 18px;
  }

  .question-mark1:hover::after {
    /* 使用 ::after 伪元素来显示文本 */
    content: " 使用本体实现资源数据的标准化描述及展示";
    position: absolute;
    top: -10px; /* 调整提示文本位置，使其位于问号的上方 */
    left: calc(100% + 5px); /* 设置文本距离问号图案的距离 */
    padding: 5px;
    background-color: #fff;
    color: #000;
    border: 1px solid #000;
    border-radius: 4px;
    display: block;
    max-width: 400px; /* 设置最大宽度 */
    white-space: nowrap; /* 防止文本换行 */
    word-wrap: break-word;
    font-size: 14px;
  }

  .question-mark22 {
    position: relative;
    display: inline-block;
    width: 20px;
    text-align: center;
    line-height: 20px;
    margin-left: 5px; /* 将右侧间距改为5px */
    font-size: 18px;
  }

  .question-mark22:hover::after {
    /* 使用 ::after 伪元素来显示文本 */
    content: " 使用实例覆盖本体";
    position: absolute;
    top: -10px; /* 调整提示文本位置，使其位于问号的上方 */
    left: calc(100% + 5px); /* 设置文本距离问号图案的距离 */
    padding: 5px;
    background-color: #fff;
    color: #000;
    border: 1px solid #000;
    border-radius: 4px;
    display: block;
    max-width: 400px; /* 设置最大宽度 */
    white-space: nowrap; /* 防止文本换行 */
    word-wrap: break-word;
    font-size: 14px;
  }

  .question-mark2 {
    position: relative;
    display: inline-block;
    width: 20px;
    text-align: center;
    line-height: 20px;
    margin-left: 5px; /* 将右侧间距改为5px */
    font-size: 18px;
  }

  .question-mark2:hover::after {
    /* 使用 ::after 伪元素来显示文本 */
    content: " 使用本体实现资源数据的标准化描述及展示";
    position: absolute;
    top: -10px; /* 调整提示文本位置，使其位于问号的上方 */
    left: calc(100% + 5px); /* 设置文本距离问号图案的距离 */
    padding: 5px;
    background-color: #fff;
    color: #000;
    border: 1px solid #000;
    border-radius: 4px;
    display: block;
    max-width: 400px; /* 设置最大宽度 */
    white-space: nowrap; /* 防止文本换行 */
    word-wrap: break-word;
    font-size: 14px;
  }
  .question-mark3 {
    position: relative;
    display: inline-block;
    width: 20px;
    text-align: center;
    line-height: 20px;
    margin-left: 5px; /* 将右侧间距改为5px */
    font-size: 18px;
  }

  .question-mark3:hover::after {
    /* 使用 ::after 伪元素来显示文本 */
    content: " 使用本体实现资源数据的标准化描述及展示，对数据属性的对象根据采集数据进行赋值";
    position: absolute;
    top: -10px; /* 调整提示文本位置，使其位于问号的上方 */
    left: calc(100% + 5px); /* 设置文本距离问号图案的距离 */
    padding: 5px;
    background-color: #fff;
    color: #000;
    border: 1px solid #000;
    border-radius: 4px;
    display: block;
    max-width: 1200px; /* 设置最大宽度 */
    white-space: nowrap; /* 防止文本换行 */
    word-wrap: break-word;
    font-size: 14px;
  }
  .box1 {
    width: 100%;
    background-color: #f2f3f5;
    margin-top: 0px;
    overflow: auto; /* 启用滚动条 */
  }

  .header_1 {
    width: 100%;
    height: 30px;
    line-height: 30px;
    padding-left: 20px;
    border-bottom: 1px solid #ccc;
    margin-bottom: 20px;
  }
  .header_2 {
    width: 100%;
    height: 30px;
    line-height: 30px;
    padding-left: 20px;
    border-bottom: 1px solid #ccc;
    margin-bottom: 0px;
    display: flex;
    align-items: center;
  }

  .object,
  .classfication {
    width: calc(50% - 30px);
    margin-left: 20px;
    display: inline-block;
    vertical-align: top;
    margin-bottom: 20px;
  }
  .mapping {
    width: calc(100% - 42px);
    margin-left: 20px;
    display: inline-block;
    vertical-align: top;
    margin-bottom: 20px;
  }
  .object .title,
  .classfication .title,
  .mapping .title {
    display: block;
    padding-bottom: 10px;
    margin-top: 20px;
  }

  .btns {
    width: calc(100% - 40px);
    margin-left: 20px;
    margin-top: 10px;
    margin-bottom: 20px;
  }

  .btns el-button {
    margin-right: 20px;
  }

  .input-with-select {
    max-width: calc(100% - 40px);
  }
  .file {
    width: 20px;
    height: 20px;
  }
}
</style>
